package com.diuse.lib.util.helper;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Java bean helper class.
 * @author Fu Mingjie
 */
public class ClazzHelper {
	/**
	 * Shutcut for Class.forName
	 * @param name Class name
	 * @return Class
	 */
	public static boolean existed(String name) {
		try {
		    Class.forName(name);
		} catch (ClassNotFoundException e) {
			return false;
		}

		return true;
	}

	/**
	 * Shutcut for Class.forName
	 * @param name Class name
	 * @return Class
	 */
	public static Class forName(String name) {
		try {
			return Class.forName(name);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * Get method object from class.
	 * @param clazz Class object
	 * @param name Method name
	 * @return Method object
	 */
    public static Method getMethod(Class<? extends Object> clazz, final String name) {
    	if (clazz == null) {
    		return null;
    	}

    	Method[] methods = clazz.getDeclaredMethods();
    	for (Method m : methods) {
    		if (name.equals(m.getName())) {
    			return m;
    		}
    	}

    	Class<? extends Object> superClass = clazz.getSuperclass();
    	if (superClass == null || "java.lang.Object".equals(superClass.getName())) {
    		return null;
    	}

    	return getMethod(clazz.getSuperclass(), name);
    }


    /**
     * Get a Field instance from a class.
     * @param c Class
     * @param name field name to get.
     * @return Field instance
     */
    public static Field getDeclaredField(final Class<? extends Object> c, final String name) {
        try {
            return c.getDeclaredField(name);
        } catch (NoSuchFieldException e) {
            if (c.getSuperclass() != null) {
                return getDeclaredField(c.getSuperclass(), name);
            }
            return null;
        }
    }

    /**
     * Get all Fields from a class.
     * @param c Class
     * @return Fields
     */
    public static List<Field> getDeclaredFields(final Class<? extends Object> c) {
    	List<Field> fieldList = new ArrayList<Field>();
    	fieldList.addAll(Arrays.asList(c.getDeclaredFields()));
    	
    	Class<? extends Object> clazz = c;
    	while ((clazz = clazz.getSuperclass()) != null) {
    		fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
    	}
    	
    	return fieldList;
    }

    /**
     * Class newInstance.
     * @param clazz class name
     * @return Object
     */
    public static Object newInstance(final Class<? extends Object> clazz) {
        try {
            return clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

}

